using Jupiter.Infrastructure.Cache.Interfaces;
using Jupiter.Infrastructure.Domain;
using Jupiter.Infrastructure.Domain.SqlSugar.Basic;
using Jupiter.Infrastructure.Permission;
using Jupiter.Infrastructure.Permission.DataPermissions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Localization;
using Wips.Domain.Models.Authorities.Model;

namespace Wips.AppService.SqlSugar;

/// <summary>
/// 查询基类
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class BaseQueryAppService<TEntity> : AppServiceQueryBase<TEntity> where TEntity : EntityBase
{
    private readonly ICacheManager _cacheManager;

    private readonly IDataPermission? _dataPermission;


    private void AddFilter(ISqlSugarClient dbContext)
    {
        if (dbContext.QueryFilter.GeFilterList.Count == 0)
        {

        }
    }



    /// <summary>
    /// 获取下属的userIds
    /// </summary>
    /// <param name="nowUserOrg"></param>
    /// <returns></returns>
    protected string GetSubordinate(ISugarQueryable<string?> nowUserOrg)
    {
        var orgId = GetTreeOrganizationIds(nowUserOrg); //下级组织架构
        var position3 = SqlFunc.Subqueryable<PositionUser>()
            .Where(c => c.UserId == UserId)
            .Select(c => c.PositionId);
        var position = GetTreePositionIds(position3); //下级岗位，不含同级

        var queryOrgUserId3 = SqlFunc.Subqueryable<OrganizationUser>()
            .Where(c => orgId.Contains(c.OrganizationId))
            .Select(c => c.UserId);
        var userQuery3 = SqlFunc.Subqueryable<PositionUser>()
            .Where(c => position.Contains(c.PositionId))
            .Where(c => c.UserId == queryOrgUserId3)
            .Select(c => c.UserId);
        return userQuery3;
    }

    /// <summary>
    /// 获取下属的userIds
    /// </summary>
    /// <param name="nowUserOrg"></param>
    /// <returns></returns>
    protected string GetSubordinate(IList<string?> nowUserOrg)
    {
        var orgId = GetTreeOrganizationIds(nowUserOrg); //下级组织架构
        var position3 = SqlFunc.Subqueryable<PositionUser>()
            .Where(c => c.UserId == UserId)
            .Select(c => c.PositionId);
        var position = GetTreePositionIds(position3); //下级岗位，不含同级

        var queryOrgUserId3 = SqlFunc.Subqueryable<OrganizationUser>()
            .Where(c => orgId.Contains(c.OrganizationId))
            .Select(c => c.UserId);
        var userQuery3 = SqlFunc.Subqueryable<PositionUser>()
            .Where(c => position.Contains(c.PositionId))
            .Where(c => c.UserId == queryOrgUserId3)
            .Select(c => c.UserId);
        return userQuery3;
    }

    /// <summary>
    /// 获取下级所有组织机构（包含自己所在的组织架构）
    /// </summary>
    /// <param name="parentIds"></param>
    /// <returns></returns>
    protected List<string?> GetTreeOrganizationIds(ISugarQueryable<string?> parentIds)
    {
        //这里后续换成缓存实现
        var periods = parentIds.ToList();
        var allOrg = QueryNoTracking<Organization>()
            .Select(c => new Organization { Id = c.Id, ParentId = c.ParentId }).ToList();
        return periods.Concat(GetTreeChildOrganizationIds(allOrg, periods)).ToList();
    }

    /// <summary>
    /// 获取下级所有组织机构（包含自己所在的组织架构）
    /// </summary>
    /// <param name="parentIds"></param>
    /// <returns></returns>
    protected List<string?> GetTreeOrganizationIds(IList<string?> parentIds)
    {
        //这里后续换成缓存实现
        var periods = parentIds.ToList();
        var allOrg = QueryNoTracking<Organization>()
            .Select(c => new Organization { Id = c.Id, ParentId = c.ParentId }).ToList();
        return periods.Concat(GetTreeChildOrganizationIds(allOrg, periods)).ToList();
    }

    /// <summary>
    /// 组织架构递归
    /// </summary>
    /// <param name="allOrg"></param>
    /// <param name="parentIds"></param>
    /// <returns></returns>
    private List<string?> GetTreeChildOrganizationIds(List<Organization> allOrg, List<string?> parentIds)
    {
        var childQuery = allOrg
            .Where(c => parentIds.Contains(c.ParentId))
            .Select(c => c.Id).ToList();
        if (childQuery.Count > 0)
        {
            return childQuery.Concat(GetTreeChildOrganizationIds(allOrg, childQuery)).ToList();
        }

        return new List<string?>();
    }


    /// <summary>
    /// 获取下级所有岗位（不含自己的岗位）
    /// </summary>
    /// <param name="parentIds"></param>
    /// <returns></returns>
    private List<string?> GetTreePositionIds(string parentIds)
    {
        //这里后续换成缓存实现
        var periods = QueryNoTracking<Position>()
            .Where(c => c.Id == parentIds)
            .Select(c => c.Id)
            .ToList();
        var allPosition = QueryNoTracking<Position>()
            .Select(c => new Position { Id = c.Id, ParentId = c.ParentId }).ToList();
        return periods.Concat(GetTreeChildPositionIds(allPosition, periods)).ToList();
    }

    /// <summary>
    /// 岗位递归
    /// </summary>
    /// <param name="allPosition"></param>
    /// <param name="parentIds"></param>
    /// <returns></returns>
    private List<string?> GetTreeChildPositionIds(List<Position> allPosition, List<string?> parentIds)
    {
        var childQuery = allPosition
            .Where(c => parentIds.Contains(c.ParentId))
            .Select(c => c.Id).ToList();
        if (childQuery.Count > 0)
        {
            return childQuery.Concat(GetTreeChildPositionIds(allPosition, childQuery)).ToList();
        }

        return new List<string?>();
    }


    /// <summary>
    /// 获取用户角色的sql
    /// </summary>
    /// <param name="userId"></param>
    /// <returns></returns>
    protected async Task<List<string>?> GetUserRoleSql(string userId)
    {
        return await _cacheManager.GetOrCreateAsync("ROLEKEY:" + userId, async () =>
        {
            // 读取组织架构用户
            var organizationIds = await QueryNoTracking<OrganizationUser>()
                .InnerJoin<Organization>((ou, og) => ou.OrganizationId == og.Id)
                .Where((ou, og) => ou.UserId == userId)
                // 组织架构是启用的
                .Where((ou, og) => (int)og.Status == 1)
                .Select((ou, og) => ou.OrganizationId)
                .ToListAsync();

            // 读取职位用户
            var positionIds = await QueryNoTracking<PositionUser>()
                .InnerJoin<Position>((pu, po) => pu.PositionId == po.Id)
                .Where((pu, po) => pu.UserId == userId)
                // 职位是启用的
                .Where((pu, po) => (int)po.Status == 1)
                .Select((pu, po) => pu.PositionId)
                .ToListAsync();


            var organRole = await QueryNoTracking<OrganizationRole>()
                .InnerJoin<Organization>((o, og) => o.OrganizationId == og.Id)
                .InnerJoin<Role>((o, og, r) => o.RoleId == r.Id)
                .Where((o, og, r) => organizationIds.Contains(o.OrganizationId))
                // 组织架构是启用的
                .Where((o, og, r) => (int)og.Status == 1)
                // 角色是启用的
                .Where((o, og, r) => (int)r.Status == 1)
                .Select((o, og, r) => o.RoleId).ToListAsync();

            var posRole = await QueryNoTracking<PositionRole>()
                .InnerJoin<Position>((pr, po) => pr.PositionId == po.Id)
                .InnerJoin<Role>((pr, po, r) => pr.RoleId == r.Id)
                .Where((pr, po, r) => positionIds.Contains(pr.PositionId))
                // 职位是启用的
                .Where((pr, po, r) => (int)po.Status == 1)
                // 角色是启用的
                .Where((pr, po, r) => (int)r.Status == 1)
                .Select((pr, po, r) => pr.RoleId).ToListAsync();

            var userRole = await QueryNoTracking<UserRole>()
                .InnerJoin<Role>((pr, po) => pr.RoleId == po.Id)
                // 角色是启用的
                .Where((pr, po) => (int)po.Status == 1)
                .Where((pr, po) => pr.UserId == userId)
                .Select((pr, po) => pr.RoleId).ToListAsync();

            List<string> roleIds = new List<string>();

            roleIds = roleIds.Concat(organRole).ToList();
            roleIds = roleIds.Concat(posRole).ToList();
            roleIds = roleIds.Concat(userRole).ToList();
            return roleIds.Distinct().ToList();
        }, new TimeSpan(0, 0, 0, 20));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="dbContext"></param>
    /// <param name="securityContextAccessor"></param>
    /// <param name="configuration"></param>
    /// <param name="cacheManager"></param>
    /// <param name="dataPermission"></param>
    /// <param name="localizer"></param>
    public BaseQueryAppService(ISqlSugarClient dbContext, ISecurityContextAccessor securityContextAccessor,
        IConfiguration? configuration, ICacheManager cacheManager,
        IDataPermission? dataPermission, IStringLocalizer? localizer) : base(dbContext,
        securityContextAccessor,
        configuration, cacheManager, dataPermission, localizer)
    {
        _cacheManager = cacheManager;
        _dataPermission = dataPermission;
        AddFilter(dbContext);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="dbContext"></param>
    /// <param name="securityContextAccessor"></param>
    /// <param name="configuration"></param>
    /// <param name="cacheManager"></param>
    /// <param name="dataPermission"></param>
    public BaseQueryAppService(ISqlSugarClient dbContext, ISecurityContextAccessor securityContextAccessor,
        IConfiguration? configuration, ICacheManager cacheManager,
        IDataPermission? dataPermission) : base(dbContext,
        securityContextAccessor,
        configuration, cacheManager, dataPermission, null)
    {
        _cacheManager = cacheManager;
        _dataPermission = dataPermission;
        AddFilter(dbContext);
    }
}